package com.qianli.cashmama.trade.domain.model;

import com.qianli.cashmama.trade.common.enums.BillPaidStatusEnum;
import com.qianli.cashmama.trade.common.enums.BillStatusEnum;
import com.qianli.cashmama.trade.common.error.TradeErrorCodeEnum;
import com.qianli.cashmama.trade.common.exceptions.TradeException;
import com.qianli.cashmama.trade.common.utils.CalculatorUtils;
import com.qianli.cashmama.trade.domain.StateMachine;

import java.math.BigDecimal;
import java.util.Date;

/**
 * Created with IntelliJ IDEA.
 * User: sm
 * Date: 2017/7/20
 * Time: 下午3:24
 */
public class BillBase extends BaseModel {

    /**
     * 账单编号
     */
    private String billNo;
    /**
     * 交易编号
     */
    private String tradeNo;
    /**
     * 当前期数
     */
    private Integer currentPeriod;
    /**
     * 账单状态
     */
    private BillStatusEnum status;
    /**
     * 还款状态
     */
    private BillPaidStatusEnum paidStatus;
    /**
     * 借款金额
     */
    private BigDecimal borrowCapital;
    /**
     * 到账金额
     */
    private BigDecimal receivedCapital;
    /**
     * 利息(个税贷借款利息)
     */
    private BigDecimal interestFee;
    /**
     * 服务费(个税贷=总本金*1%)
     */
    private BigDecimal borrowServiceFee;
    /**
     * 应还金额
     */
    private BigDecimal repaymentCapital;
    /**
     * 已还金额
     */
    private BigDecimal paidCapital;
    /**
     * 优惠金额
     */
    private BigDecimal discountCapital;
    /**
     * 展期次数
     */
    private Integer extensionCount;
    /**
     * 应还时间
     */
    private Date repaymentDate;
    /**
     * 还清时间
     */
    private Date payOffDate;
    /**
     * 逾期服务费
     */
    private BigDecimal overdueServiceFee;
    /**
     * 逾期费(按天计息)
     */
    private BigDecimal overdueFee;

    /**
     * 理论应还总金额(账单结清时计算)
     */
    private BigDecimal theoreticalTotalAmount;

    /**
     * 产品类目
     */
    private String productCategory;

    /**
     * 产品编码
     */
    private String productCode;

    public String getProductCategory() {
        return productCategory;
    }

    public BillBase setProductCategory(String productCategory) {
        this.productCategory = productCategory;
        return this;
    }

    public String getProductCode() {
        return productCode;
    }

    public BillBase setProductCode(String productCode) {
        this.productCode = productCode;
        return this;
    }

    public BigDecimal getReceivedCapital() {
        return receivedCapital;
    }

    public BillBase setReceivedCapital(BigDecimal receivedCapital) {
        this.receivedCapital = receivedCapital;
        return this;
    }

    public BigDecimal getInterestFee() {
        return interestFee;
    }

    public BillBase setInterestFee(BigDecimal interestFee) {
        this.interestFee = interestFee;
        return this;
    }

    public BigDecimal getBorrowServiceFee() {
        return borrowServiceFee;
    }

    public BillBase setBorrowServiceFee(BigDecimal borrowServiceFee) {
        this.borrowServiceFee = borrowServiceFee;
        return this;
    }

    public String getBillNo() {
        return billNo;
    }

    public BillBase setBillNo(String billNo) {
        this.billNo = billNo;
        return this;
    }

    public String getTradeNo() {
        return tradeNo;
    }

    public BillBase setTradeNo(String tradeNo) {
        this.tradeNo = tradeNo;
        return this;
    }

    public Integer getCurrentPeriod() {
        return currentPeriod;
    }

    public BillBase setCurrentPeriod(Integer currentPeriod) {
        this.currentPeriod = currentPeriod;
        return this;
    }

    public BillStatusEnum getStatus() {
        return status;
    }

    public BillBase setStatus(BillStatusEnum status) {
        this.status = status;
        return this;
    }

    public BillPaidStatusEnum getPaidStatus() {
        return paidStatus;
    }

    public BillBase setPaidStatus(BillPaidStatusEnum paidStatus) {
        this.paidStatus = paidStatus;
        return this;
    }

    public BigDecimal getBorrowCapital() {
        return borrowCapital;
    }

    public BillBase setBorrowCapital(BigDecimal borrowCapital) {
        this.borrowCapital = borrowCapital;
        return this;
    }

    public BigDecimal getRepaymentCapital() {
        return repaymentCapital;
    }

    public BillBase setRepaymentCapital(BigDecimal repaymentCapital) {
        this.repaymentCapital = repaymentCapital;
        return this;
    }

    public BigDecimal getPaidCapital() {
        return paidCapital;
    }

    public BillBase setPaidCapital(BigDecimal paidCapital) {
        this.paidCapital = paidCapital;
        return this;
    }

    public BigDecimal getDiscountCapital() {
        return discountCapital;
    }

    public BillBase setDiscountCapital(BigDecimal discountCapital) {
        this.discountCapital = discountCapital;
        return this;
    }

    public Date getRepaymentDate() {
        return repaymentDate;
    }

    public BillBase setRepaymentDate(Date repaymentDate) {
        this.repaymentDate = repaymentDate;
        return this;
    }

    public Date getPayOffDate() {
        return payOffDate;
    }

    public BillBase setPayOffDate(Date payOffDate) {
        this.payOffDate = payOffDate;
        return this;
    }

    public BigDecimal getOverdueServiceFee() {
        return overdueServiceFee;
    }

    public BillBase setOverdueServiceFee(BigDecimal overdueServiceFee) {
        this.overdueServiceFee = overdueServiceFee;
        return this;
    }

    public BigDecimal getOverdueFee() {
        return overdueFee;
    }

    public BillBase setOverdueFee(BigDecimal overdueFee) {
        this.overdueFee = overdueFee;
        return this;
    }

    public BigDecimal getTheoreticalTotalAmount() {
        return theoreticalTotalAmount;
    }

    public BillBase setTheoreticalTotalAmount(BigDecimal theoreticalTotalAmount) {
        this.theoreticalTotalAmount = theoreticalTotalAmount;
        return this;
    }

    @Override
    protected void doTransferStatus(String action, int targetStatus, String operator, Date operationDt, Date bizDt, String memo) {
        StateMachine stateMachine = getStatusMachine();
        boolean statusChangeAllowed = stateMachine.checkTransition(this.status.getStatus(), action, targetStatus);
        if (!statusChangeAllowed) {
            throw new TradeException(TradeErrorCodeEnum.trade_status_transfer_error);
        }

        this.status = BillStatusEnum.conventByStatus(targetStatus);
    }

    @Override
    protected StateMachine getStatusMachine() {
        return null;
    }

    public boolean isOverdue() {
        return CalculatorUtils.isOverdue(repaymentDate, payOffDate);
    }

    public int overdueDays() {
        if (paidStatus.equals(BillPaidStatusEnum.CLEAR_REPAYMENT)) {
            return 0;
        }
        return CalculatorUtils.overDueDays(repaymentDate, payOffDate);

    }

    public Integer getExtensionCount() {
        return extensionCount;
    }

    public BillBase setExtensionCount(Integer extensionCount) {
        this.extensionCount = extensionCount;
        return this;
    }
}
